package com.personal.dataconvert;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.personal.core.data.DataColumn;
import com.personal.core.data.DataRow;
import com.personal.core.data.DataTable;
import com.personal.core.utils.CoreUtil;
import com.personal.core.utils.JsonUtil;
import com.personal.dataconvert.bean.HeaderConfig;
import com.personal.dataconvert.bean.HtmlConfig;
import com.personal.dataconvert.port.Data2DataGrid;
import com.personal.dataconvert.util.ExcelHtmlUtil;

/**
 * 
 * @author cuibo
 */
public class DataTable2DataGrid implements Data2DataGrid
{
    
    
    /** 报表数据 */
    private DataTable table;

    /** splitFlag 表头分割标记。默认是点 */
    private String splitFlag = ".";
    
    /** 2017 06 02 新增手动注入HtmlConfig */
    private HtmlConfig htmlConfig;
    

    private DataTable2DataGrid()
    {
    }

    private DataTable2DataGrid(Builder builder)
    {
        this.table = builder.table;
        this.splitFlag = builder.splitFlag;
        this.htmlConfig = builder.htmlConfig;
        createHtmlConfig();
    }
    
    /**
     * 构建HtmlConfig
     * @return
     * @throws Exception
     */
    private void createHtmlConfig()
    {
        if (htmlConfig != null)
        {
            return;
        }
        htmlConfig = new HtmlConfig();
        htmlConfig.setName(table.getTableName());
        List<HeaderConfig> headerConfigs = null;
        try
        {
            headerConfigs = ExcelHtmlUtil.createTrees(table, splitFlag);
        } catch (Exception e)
        {
        }
        if (CoreUtil.isEmpty(headerConfigs))
        {
            throw new IllegalArgumentException("datatable信息不合法，创建表头配置失败！");
        }
        htmlConfig.setTableClass(CoreUtil.parseStr(table.getTag()));
        htmlConfig.setHeaderConfigs(headerConfigs);
    }

    @Override
    public String createColums() throws Exception
    {
        if (CoreUtil.isEmpty(htmlConfig.getHeaderConfigs()))
        {
            return "[]";
        }
        List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
        for (HeaderConfig config : htmlConfig.getHeaderConfigs())
        {
            list.add(headerConfig2Map(config));
        }
        return JsonUtil.toJson(list);
    }
    
    
//    @Override
//    public String createColums() throws Exception
//    {
//        if (CoreUtil.isEmpty(htmlConfig.getHeaderConfigs()))
//        {
//            return "[]";
//        }
//        StringBuilder result = new StringBuilder();
//        result.append("[\n");
//        int colIndex = -1;
//        for (HeaderConfig config : htmlConfig.getHeaderConfigs())
//        {
//            colIndex ++;
//            result.append(headerConfig2Json(config));
//            if (colIndex != htmlConfig.getHeaderConfigs().size() - 1)
//            {
//                result.append(",");
//            }
//            result.append("\n");
//        }
//        result.append("]");
//        return result.toString();
//    }
   
    @SuppressWarnings("unused")
    private String headerConfig2Json(HeaderConfig config)
    {
        StringBuilder result = new StringBuilder();
        headerConfig2JsonImpl(result, config);
        return result.toString();
    }

    /**
     * HeaderConfig转Map
     * @param config
     * @return
     */
    private Map<String, Object> headerConfig2Map(HeaderConfig config)
    {
        Map<String, Object> result = new LinkedHashMap<String, Object>();
        headerConfig2MapImpl(result, config);
        return result;
    }
    
    private void headerConfig2MapImpl(Map<String, Object> result, HeaderConfig config)
    {
        result.put("name", config.getValue());
        result.put("caption", config.getDisplayName());
        result.put("width", config.getWidth() + "");
        result.put("dataAlign", CoreUtil.isEmpty(config.getAlign()) ? HeaderConfig.CENTER : config.getAlign());
        if (config.getWidth() <= 0 )
        {
            result.put("visible", "false");
        }
        if (!CoreUtil.isEmpty(config.getChildren()))
        {
            List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
            for (HeaderConfig child : config.getChildren())
            {
                Map<String, Object> childMap = new LinkedHashMap<String, Object>();
                headerConfig2MapImpl(childMap, child);
                list.add(childMap);
                result.put("columns", list);
            }
        }
    }

    private void headerConfig2JsonImpl(StringBuilder result, HeaderConfig config)
    {
        result.append("{ \"name\":\"").append(config.getValue()).append("\", \"caption\":\"").append(config.getDisplayName())
            .append("\", \"width\":\"").append(config.getWidth()).append("\", \"dataAlign\":\"").append(CoreUtil.isEmpty(config.getAlign()) ? HeaderConfig.CENTER : config.getAlign())
            .append("\" ");
        // 如果宽度小于等于0，则设置为不可见
        if (config.getWidth() <= 0 )
        {
            result.append(", \"visible\":false ");
        }
        
        if (!CoreUtil.isEmpty(config.getChildren()))
        {
            result.append(", \"columns\":[\n ");
            for (HeaderConfig child : config.getChildren())
            {
                headerConfig2JsonImpl(result, child);
            }
            result.append("\n] ");
        }
        result.append(" }");
    }

    @Override
    public String createRows() throws Exception
    {
        if (!CoreUtil.checkDataTableHasData(table))
        {
            return "[]";
        }
        List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
        for (DataRow row : table.getRows())
        {
            Map<String, Object> map = new LinkedHashMap<String, Object>();
            for (DataColumn column : table.getColumns())
            {
                map.put(column.getColumnName(), row.getItemMap().get(column.getColumnName()));
            }
            list.add(map);
        }
        return JsonUtil.toJson(list);
    }
    
//    @Override
//    public String createRows() throws Exception
//    {
//        if (!CoreUtil.checkDataTableHasData(table))
//        {
//            return "[]";
//        }
//        List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
//        StringBuilder result = new StringBuilder();
//        result.append("[\n ");
//        int rowIndex = -1;
//        for (DataRow row : table.getRows())
//        {
//            Map<String, Object> map = new LinkedHashMap<String, Object>();
//            for (DataColumn column : table.getColumns())
//            {
//                map.put(column.getColumnName(), row.getItemMap().get(column.getColumnName()));
//            }
//            list.add(map);
//            rowIndex ++;
//            result.append(dataRow2Json(row));
//            if (rowIndex != table.getRows().size() - 1)
//            {
//                result.append(",");
//            }
//        }
//        result.append("]");
//        return result.toString();
//    }
//    
    
    @SuppressWarnings("unused")
    private String dataRow2Json(DataRow row)
    {
        StringBuilder result = new StringBuilder();
        dataRow2JsonImpl(result, row);
        return result.toString();
    }
    
    private void dataRow2JsonImpl(StringBuilder result, DataRow row)
    {
        result.append("{ ");
        int colIndex = -1;
        for (DataColumn column : table.getColumns())
        {
            colIndex ++;
            result.append("\"").append(column.getColumnName()).append("\":\"").append(CoreUtil.parseStr(row.getItemMap().get(column.getColumnName()))).append("\"");
            if (colIndex != table.getColumns().size() - 1)
            {
                result.append(",");
            }
        }
        result.append("}");
    }
    

    /**
     * 建造
     * @author cuibo
     */
    public static class Builder
    {
        private DataTable table;
        private String splitFlag = ".";
        private HtmlConfig htmlConfig;

        public Builder setDataTable(DataTable table)
        {
            this.table = table;
            return this;
        }

        public Builder setSplitFlag(String splitFlag)
        {
            this.splitFlag = splitFlag;
            return this;
        }

        public Builder setHtmlConfig(HtmlConfig htmlConfig)
        {
            this.htmlConfig = htmlConfig;
            return this;
        }
        
        public DataTable2DataGrid build()
        {
            return new DataTable2DataGrid(this);
        }
    }


}
